package image;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.IllegalFormatException;
import java.util.IllegalFormatFlagsException;
import java.util.zip.*;

public class ZipHelper {
    private static final String TAG = "image.ZipHelper";
    public static final String STICKER_FILE_ROOT = "Sticker";
    private static final byte[] zipFileHeaderSignature = {0x50, 0x4b, 0x03, 0x04};

    public static void main(String[] args) throws IOException {
        File file = new File("F:\\DownLoad\\StickerFolder\\StickerSet_\\几点了");
        File utf8File = new File(file.getParentFile().getAbsolutePath() + File.separator + "几点了(1)");
        file.renameTo(utf8File);
        System.out.println(file.getAbsolutePath());
        String dstPath = "F:\\DownLoad\\StickerFolder\\" + utf8File.getName() + ".zip";
        compress(utf8File.getAbsolutePath(), dstPath);
//        File dstFile = new File(dstPath);
//        unzip(dstFile, dstFile.getParentFile());
//        System.out.println((int) (100 * 0.23f));
    }


    public static final void unzip(String path, String dest) {
        unzip(new File(path), new File(dest));
    }

    /**
     * @param file source zip file
     * @param dest the dest folder where zip file will be unzipped to
     */
    public static final void unzip(File file, File dest) throws IllegalFormatException {
        if (verifyZip(file)) {
            try {
                ZipInputStream zip = new ZipInputStream(new BufferedInputStream(new FileInputStream(file)), Charset.forName("UTF-8"));
                ZipEntry zipEntry = null;
                while ((zipEntry = zip.getNextEntry()) != null) {
                    //遇到一个目录
                    if (zipEntry.isDirectory()) {
                        File dir = new File(dest + zipEntry.getName());
                        if (!dir.exists())
                            dir.mkdirs();
                        zip.closeEntry();
                    } else {//文件
                        System.out.println(zipEntry.getName());
                        File stickerFile = new File(dest.getAbsolutePath() + File.separator + zipEntry.getName());
                        File parentFile = stickerFile.getParentFile();
                        if (!parentFile.exists())
                            parentFile.mkdirs();
                        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(stickerFile));
                        byte[] buf = new byte[1024];
                        int len;
                        while ((len = zip.read(buf)) != -1) {
                            bos.write(buf, 0, len);
                            bos.flush();
                        }
                        bos.close();
                        zip.closeEntry();
                        if (!parentFile.exists())
                            parentFile.mkdirs();
                    }
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else
            throw new IllegalFormatFlagsException("不是压缩文件");
    }


    static final int BUFFER = 8192;

    public static void compress(String srcPath, String dstPath) throws IOException {
        File srcFile = new File(srcPath);
        File dstFile = new File(dstPath);
        if (!srcFile.exists()) {
            throw new FileNotFoundException(srcPath + "不存在！");
        }

        FileOutputStream out = null;
        ZipOutputStream zipOut = null;
        try {
            out = new FileOutputStream(dstFile);
            CheckedOutputStream cos = new CheckedOutputStream(out, new CRC32());
            zipOut = new ZipOutputStream(cos);
            String baseDir = "";
            compress(srcFile, zipOut, baseDir);
        } finally {
            if (null != zipOut) {
                zipOut.close();
                out = null;
            }

            if (null != out) {
                out.close();
            }
        }
    }

    private static void compress(File file, ZipOutputStream zipOut, String baseDir) throws IOException {
        if (file.isDirectory()) {
            compressDirectory(file, zipOut, baseDir);
        } else {
            compressFile(file, zipOut, baseDir);
        }
    }

    /**
     * 压缩一个目录
     */
    private static void compressDirectory(File dir, ZipOutputStream zipOut, String baseDir) throws IOException {
        File[] files = dir.listFiles();
        for (int i = 0; i < files.length; i++) {
            compress(files[i], zipOut, baseDir + dir.getName() + "/");
        }
    }

    /**
     * 压缩一个文件
     */
    private static void compressFile(File file, ZipOutputStream zipOut, String baseDir) throws IOException {
        if (!file.exists()) {
            return;
        }

        BufferedInputStream bis = null;
        try {
            bis = new BufferedInputStream(new FileInputStream(file));
            ZipEntry entry = new ZipEntry(baseDir + file.getName());
            zipOut.putNextEntry(entry);
            int count;
            byte data[] = new byte[BUFFER];
            while ((count = bis.read(data, 0, BUFFER)) != -1) {
                zipOut.write(data, 0, count);
            }

        } finally {
            if (null != bis) {
                bis.close();
            }
        }
    }


    private static boolean verifyZip(File file) {
        boolean isValid = false;

        if (!file.exists()) return isValid;

        try {
            FileInputStream fis = new FileInputStream(file);
            byte[] signature = new byte[4];
            fis.read(signature);
            if (Arrays.equals(signature, zipFileHeaderSignature))
                isValid = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return isValid;
    }
}
